<template>
	<el-form
		ref="refMyForm"
		:rules="defaultRules"
		:validate-on-rule-change="false"
		:disabled="detail"
		v-bind="$attrs"
		:class="[query ? 'myQueryForm' : 'validate--bottom']"
		@submit.prevent
		@keyup.enter="query ? searchFn?.() : ''"
	>
		<slot v-bind="Object.assign({ query, detail, refMyForm }, $attrs)">
			<my-form-item v-bind="Object.assign({ formItem, query, detail, searchFn, refMyForm }, $attrs)">
				<!-- 插槽穿透 -->
				<template v-for="slotKey in Object.keys($slots)" :key="slotKey" #[slotKey]="obj">
					<slot :name="slotKey" v-bind="obj"></slot>
				</template>
			</my-form-item>
		</slot>
	</el-form>
</template>

<script setup name="MyForm" lang="ts">
import { FormInstance } from 'element-plus';

const refMyForm = shallowRef<FormInstance>();

const isArray = (val: any) => {
	return Object.prototype.toString.call(val) === '[object Array]';
};

/***
 * props
 * @property {Array} formItem 生成form表单的配置数组
 * @property {Boolean} query 是否默认添加查询 重置按钮
 * @property {Object} rules form表单的校验对象
 * @property {Boolean} [detail=false] 表单是否为详情展示表单默认为FALSE
 * @property {Function} [searchFn] 查询表单，查询函数
 */
const props = withDefaults(
		defineProps<{
			formItem?: formItemType[];
			query?: boolean;
			rules?: objType;
			detail?: boolean;
			searchFn?: (type?: boolean) => void;
		}>(),
		{
			formItem: () => [],
			query: false,
			rules: () => ({}),
			detail: false
		}
	),
	// 默认必填
	defaultRules = computed(() => {
		if (!props.query && !props.detail) {
			const rules = Object.create(null);
			props.formItem.forEach((item) => {
				if (item.prop) {
					if (item.required) {
						rules[item.prop] = [
							{
								required: true,
								message: `${item.label}不能为空`,
								trigger: item.trigger || ['change', 'blur']
							}
						];
					}
					if (props.rules[`${item.prop}`]) {
						if (rules[item.prop])
							rules[item.prop].push(...(isArray(props.rules[`${item.prop}`]) ? props.rules[`${item.prop}`] : [props.rules[`${item.prop}`]]));
						else rules[item.prop] = props.rules[`${item.prop}`];
					}
				}
			});
			return rules;
		} else {
			return {};
		}
	});

// 查询表单时，查询函数必需传递
watch(
	() => props.query,
	(val) => {
		if (val) {
			if (!props.searchFn) throw new Error('query is true，searchFn is required');
		}
	},
	{
		immediate: true
	}
);

// 暴露el-form自身方法
defineExpose(
	new Proxy(
		{},
		{
			get(_target, key) {
				return refMyForm.value?.[key as keyof FormInstance];
			},
			has(_target, key) {
				return key in refMyForm.value!;
			}
		}
	)
);
</script>

<style lang="scss" scoped>
:deep() {
	// .el-form-item,
	.el-select,
	.el-cascader,
	.el-input-number,
	.el-input__wrapper,
	.el-textarea,
	.el-input {
		box-sizing: border-box;
		width: 100% !important;
	}
}
</style>
